package com.sixnimmt.app.server.game;

import java.io.IOException;
import java.util.logging.Logger;

import javax.servlet.ServletException;

import org.atmosphere.cpr.Broadcaster;
import org.atmosphere.cpr.BroadcasterFactory;
import org.atmosphere.cpr.DefaultBroadcaster;
import org.atmosphere.cpr.MetaBroadcaster;
import org.atmosphere.gwt.server.AtmosphereGwtHandler;
import org.atmosphere.gwt.server.GwtAtmosphereResource;

import com.sixnimmt.app.server.game.domain.Player;
import com.sixnimmt.app.shared.game.notification.PlayerHasQuitNotification;

public class RetrieveGameNotificationsHandler extends AtmosphereGwtHandler {

	public static final String BROADCASTER_PREFIX_ID = "/game/";
	public static final String ALL_PLAYERS = "*";

	private static final Logger log = Logger.getLogger(RetrieveGameNotificationsHandler.class.getName());

	// five minutes
	private static final int TIMEOUT = 300000;

	@Override
	public int doComet(GwtAtmosphereResource resource) throws ServletException, IOException {

		String playerName = resource.getRequest().getParameter("playerName");
		String sessionId = resource.getRequest().getSession().getId();
		log.info("new comet from resourceID " + resource.getConnectionID() + " to retrieve game notifications from "
				+ playerName + " with session id " + sessionId);

		Player p = GameHolder.getGame().getPlayers().get(playerName);
		if (p == null) {
			log.warning("Player " + playerName + " is not in game");
			throw new ServletException("Cannot recognize this player !");
		} else if (!p.getSessionId().equals(sessionId)) {
			log.warning("Player " + playerName + " is in game but with different session id (" + p.getSessionId()
					+ " != " + sessionId + ")");
			throw new ServletException("Cannot recognize this player !");
		}
		p.setCometId(resource.getConnectionID());

		String broadcast_id = BROADCASTER_PREFIX_ID + playerName;
		Broadcaster broadcaster = BroadcasterFactory.getDefault().lookup(Broadcaster.class, broadcast_id);
		if (broadcaster == null) {
			broadcaster = BroadcasterFactory.getDefault().get(DefaultBroadcaster.class, broadcast_id);
		}
		resource.getAtmosphereResource().setBroadcaster(broadcaster);

		return NO_TIMEOUT;
	}

	@Override
	public void cometTerminated(GwtAtmosphereResource cometResponse, boolean serverInitiated) {
		log.info("comet terminated from resourceID " + cometResponse.getConnectionID() + "  (" + serverInitiated + ")");

		for (Player player : GameHolder.getGame().getPlayers().values()) {
			if (player.getCometId() == cometResponse.getConnectionID()) {
				log.info("Player " + player.getName() + " has quit !");
				MetaBroadcaster.getDefault().broadcastTo(BROADCASTER_PREFIX_ID + ALL_PLAYERS,
						new PlayerHasQuitNotification(player.getName()));
				return;
			}
		}
	}
}
